home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / ODF Release 3 / ODFDev / Draw / Sources / DrawView.cpp < prev    next >
Encoding:
Text File  |  1996-12-16  |  15.7 KB  |  581 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                DrawView.cpp
  4. //    Release Version:    $ ODF 3 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "ODFDraw.hpp"
  11.  
  12. #ifndef DRAWVIEW_H
  13. #include "DrawView.h"
  14. #endif
  15.  
  16. #ifndef DEFINES_K
  17. #include "Defines.k"
  18. #endif
  19.  
  20. #ifndef DRAWPART_H
  21. #include "DrawPart.h"
  22. #endif
  23.  
  24. #ifndef DRAWFRM_H
  25. #include "DrawFrm.h"
  26. #endif
  27.  
  28. #ifndef DRAWSEL_H
  29. #include "DrawSel.h"
  30. #endif
  31.  
  32. #ifndef BASESHP_H
  33. #include "BaseShp.h"
  34. #endif
  35.  
  36. #ifndef BOUNDSHP_H
  37. #include "BoundShp.h"
  38. #endif
  39.  
  40. #ifndef LINESHP_H
  41. #include "LineShp.h"
  42. #endif
  43.  
  44. #ifndef OVALSHP_H
  45. #include "OvalShp.h"
  46. #endif
  47.  
  48. #ifndef RECTSHP_H
  49. #include "RectShp.h"
  50. #endif
  51.  
  52. #ifndef RRECTSHP_H
  53. #include "RRectShp.h"
  54. #endif
  55.  
  56. #ifndef TEXTSHP_H
  57. #include "TextShp.h"
  58. #endif
  59.  
  60. #ifndef DRAWPRXY_H
  61. #include "DrawPrxy.h"
  62. #endif
  63.  
  64. #ifndef SHPTRAKR_H
  65. #include "ShpTrakr.h"
  66. #endif
  67.  
  68. #ifndef DRAWCMDS_H
  69. #include "DrawCmds.h"
  70. #endif
  71.  
  72. #ifndef DRAWCLIP_H
  73. #include "DrawClip.h"
  74. #endif
  75.  
  76. #ifndef UTILS_H
  77. #include "Utils.h"
  78. #endif
  79.  
  80. #ifndef DRWDDCMD_H
  81. #include "DrwDDCmd.h"
  82. #endif
  83.  
  84. #ifndef DRAWCONT_H
  85. #include "DrawCont.h"
  86. #endif
  87.  
  88. // ----- Framework Layer -----
  89.  
  90. #ifndef FWUTIL_H
  91. #include "FWUtil.h"
  92. #endif
  93.  
  94. #ifndef FWEVEDEF_H
  95. #include "FWEveDef.h"
  96. #endif
  97.  
  98. #ifndef FWPRESEN_H
  99. #include "FWPresen.h"
  100. #endif
  101.  
  102. #ifndef FWSCROLR_H
  103. #include "FWScrolr.h"
  104. #endif
  105.  
  106. #ifndef FWSCLBAR_H
  107. #include "FWSclBar.h"
  108. #endif
  109.  
  110. #ifndef FWGROWBX_H
  111. #include "FWGrowBx.h"
  112. #endif
  113.  
  114. #ifndef FWCONTXT_H
  115. #include "FWContxt.h"
  116. #endif
  117.  
  118. #ifndef FWCLPCMD_H
  119. #include "FWClpCmd.h"
  120. #endif
  121.  
  122. // ----- OS Layer -----
  123.  
  124. #ifndef FWMENU_H
  125. #include "FWMenu.h"
  126. #endif
  127.  
  128. #ifndef FWRECSHP_H
  129. #include "FWRecShp.h"
  130. #endif
  131.  
  132. #ifndef FWCURSOR_H
  133. #include "FWCursor.h"
  134. #endif
  135.  
  136. #ifndef FWEVENT_H
  137. #include "FWEvent.h"
  138. #endif
  139.  
  140. #ifndef FWODGEOM_H
  141. #include "FWODGeom.h"
  142. #endif
  143.  
  144. #ifndef FWLINSHP_H
  145. #include "FWLinShp.h"
  146. #endif
  147.  
  148. #ifndef FWBMPSHP_H
  149. #include "FWBmpShp.h"
  150. #endif
  151.  
  152. #ifndef SLMixOS_H
  153. #include "SLMixOS.h"
  154. #endif
  155.  
  156. // ----- OpenDoc Includes -----
  157.  
  158. #ifndef SOM_Module_OpenDoc_Commands_defined
  159. #include <CmdDefs.xh>
  160. #endif
  161.  
  162. #ifndef SOM_Module_OpenDoc_StdProps_defined
  163. #include <StdProps.xh>
  164. #endif
  165.  
  166. #ifndef SOM_ODSession_xh
  167. #include <ODSessn.xh>
  168. #endif
  169.  
  170. #ifndef SOM_ODDispatcher_xh
  171. #include <Disptch.xh>
  172. #endif
  173.  
  174. //========================================================================================
  175. // RunTime Info
  176. //========================================================================================
  177.  
  178. #ifdef FW_BUILD_MAC
  179. #pragma segment odfdrawframes
  180. #endif
  181.  
  182. FW_DEFINE_CLASS_M1(CDrawView, FW_CSuperView)
  183.  
  184. const FW_ClassTypeConstant LDrawView = FW_TYPE_CONSTANT('d','r','v','w');
  185. FW_REGISTER_ARCHIVABLE_CLASS(LDrawView, CDrawView, CDrawView::Create, FW_CView::Read, CDrawView::Destroy, FW_CView::Write)
  186.  
  187. //========================================================================================
  188. // CDrawView
  189. //========================================================================================
  190.  
  191. //----------------------------------------------------------------------------------------
  192. // CDrawView::CDrawView
  193. //----------------------------------------------------------------------------------------
  194.  
  195. CDrawView::CDrawView(Environment* ev) :
  196.     FW_CSuperView(ev),
  197.     fDrawPart(NULL),
  198.     fDrawFrame(NULL),
  199.     fDrawPartContent(NULL)
  200. {    
  201. }
  202.  
  203. //----------------------------------------------------------------------------------------
  204. // CDrawView::~CDrawView
  205. //----------------------------------------------------------------------------------------
  206.  
  207. CDrawView::~CDrawView()
  208. {
  209. }
  210.  
  211. //----------------------------------------------------------------------------------------
  212. // CDrawView::Draw
  213. //----------------------------------------------------------------------------------------
  214.  
  215. void CDrawView::Draw(Environment *ev, ODFacet* odFacet, ODShape* invalidShape)
  216. {
  217.     // Render inside the content view
  218.     FW_CViewContext vc(ev, this, odFacet, invalidShape);
  219.     FW_CRect invalidRect;
  220.     vc.GetClipRect(invalidRect);
  221.  
  222.     FW_CRectShape::RenderRect(vc, invalidRect, FW_kFill, FW_kWhiteEraseInk);
  223.     
  224.     // ----- Determine what to Render -----
  225.     ODCanvas* canvas = odFacet->GetCanvas(ev);
  226.     FW_Boolean dynamicCanvas = canvas->IsDynamic(ev);
  227.  
  228.     if (dynamicCanvas)
  229.     {
  230.         FW_CRectShape::RenderRect(vc, invalidRect, FW_kFill, FW_kRGBWhite);
  231.         DrawGrid(ev, vc, invalidRect);    // Render the grid
  232.     }
  233.  
  234.     // ----- Render every shape -----
  235.     FW_CRect updateBox;
  236.     CDrawContentShapeIterator ite(fDrawPartContent);
  237.     for (CBaseShape* theShape = ite.First(); ite.IsNotComplete(); theShape = ite.Next())
  238.     {
  239.         theShape->GetUpdateBox(updateBox);
  240.         if (invalidRect.IsIntersecting(updateBox))
  241.             theShape->RenderShape(ev, odFacet, vc);
  242.     }
  243.  
  244.     // ----- Render selections Handles -----
  245.     FW_CFrame* frame = GetFrame(ev);
  246.     if (frame->HasSelectionFocus(ev) && dynamicCanvas && frame->GetWindow(ev)->IsActive(ev))    // Do not render handles for print / print preview
  247.         fDrawFrame->GetSelection(ev)->RenderSelectionHandles(ev, vc, fDrawFrame->GetZoomFactor());
  248. }
  249.  
  250. //----------------------------------------------------------------------------------------
  251. //    CDrawView::InternalTransformChanged
  252. //----------------------------------------------------------------------------------------
  253.  
  254. void CDrawView::InternalTransformChanged(Environment *ev)
  255. {
  256.     // InternalTransformChanged can be called before fDrawPart as been initialized
  257.     if (fDrawPart != NULL)
  258.     {
  259.         // ----- Set purgeable flag according to visibility -----
  260.         FW_CRect bounds = GetBoundsInContent(ev);
  261.         CDrawContentShapeIterator ite(fDrawPart->GetDrawContent());
  262.         for (CBaseShape* theShape = ite.First(); ite.IsNotComplete(); theShape = ite.Next())
  263.             theShape->MakePurgeable(ev, fDrawFrame, bounds);
  264.  
  265.         CDrawFacetClipper facetClipper(fDrawPart);
  266.         facetClipper.Clip(ev, fDrawFrame->GetPresentation(ev), NULL);
  267.     }
  268. }
  269.  
  270. //----------------------------------------------------------------------------------------
  271. // CDrawView::AdjustToNewLayout
  272. //----------------------------------------------------------------------------------------
  273.  
  274. void CDrawView::AdjustToNewLayout(Environment *ev, 
  275.                                 const FW_CPoint& oldExtent, 
  276.                                 const FW_CPoint& newExtent, 
  277.                                 FW_ERedrawVerb redraw)
  278. {
  279. FW_UNUSED(oldExtent);
  280. FW_UNUSED(newExtent);
  281.  
  282.     fDrawFrame->AdjustContentViewSize(ev, redraw);
  283. }
  284.     
  285. //----------------------------------------------------------------------------------------
  286. // CDrawView::AdjustCursor
  287. //----------------------------------------------------------------------------------------
  288.  
  289. FW_Handled CDrawView::AdjustCursor(Environment *ev, ODFacet* facet, const FW_CPoint& where, ODEventInfo* eventInfo)
  290. {
  291.     FW_Handled cursorAdjusted = FW_CView::AdjustCursor(ev, facet, where, eventInfo);
  292.     
  293.     if (cursorAdjusted == FW_kNotHandled && 
  294.         fDrawPart->GetLastActiveFrame(ev) == (FW_CFrame*)fDrawFrame && 
  295.             fDrawPart->GetTool() != kSelectTool)
  296.     {
  297.         FW_gCrossHairCursor.Select();
  298.         cursorAdjusted = FW_kHandled;
  299.     }
  300.  
  301.     return cursorAdjusted;
  302. }
  303.  
  304. //----------------------------------------------------------------------------------------
  305. //    CDrawView::DoVirtualKeyDown
  306. //----------------------------------------------------------------------------------------
  307.  
  308. FW_Handled CDrawView::DoVirtualKeyDown(Environment* ev, const FW_CVirtualKeyEvent& theVirtualKeyEvent)
  309. {    
  310.     FW_Handled wasHandled = FW_kNotHandled;
  311.     
  312.     switch (theVirtualKeyEvent.GetKeyCode(ev))
  313.     {
  314.         case FW_kVKBackspace:
  315.         case FW_kVKClear:
  316.             if (!fDrawFrame->GetSelection(ev)->IsEmpty(ev))
  317.             {
  318.                 FW_CClipboardCommand* cmd = GetFrame(ev)->NewClipboardCommand(ev, kODCommandClear);
  319.                 if (cmd)
  320.                 {
  321.                     cmd->Execute(ev);
  322.                     wasHandled = FW_kHandled;
  323.                 }
  324.             }
  325.             break;
  326.     }
  327.  
  328.     return wasHandled;
  329. }
  330.  
  331. //----------------------------------------------------------------------------------------
  332. // CDrawView::WantsToBeTarget: 
  333. //----------------------------------------------------------------------------------------
  334.  
  335. FW_Boolean CDrawView::WantsToBeTarget(Environment* ev)
  336. {
  337. FW_UNUSED(ev);
  338.     return TRUE;
  339. }
  340.  
  341. //----------------------------------------------------------------------------------------
  342. // CDrawView::DoMouseDown
  343. //----------------------------------------------------------------------------------------
  344.  
  345. FW_Handled CDrawView::DoMouseDown(Environment *ev, const FW_CMouseEvent& theMouseEvent)
  346. {
  347.     ODFacet*         theFacet = theMouseEvent.GetFacet(ev);
  348.     CDrawSelection*    selection = fDrawFrame->GetSelection(ev);
  349.     
  350.     if (fDrawPart->GetTool() == kSelectTool)
  351.     {
  352.         FW_Handled handled = FW_kNotHandled;
  353.         
  354.         if (selection->IsMouseInDraggableItem(ev, fDrawFrame, theMouseEvent, FALSE))
  355.         {
  356.             if (fDrawFrame->Drag(ev, theMouseEvent))
  357.                 handled = FW_kHandled;
  358.         }
  359.         else if (!selection->Resize(ev, theMouseEvent))
  360.         {
  361.             selection->SelectWithRectangle(ev, theMouseEvent);
  362.             handled = FW_kHandled;
  363.         }
  364.                             
  365.         return handled;
  366.     }
  367.     
  368.     // ----- If read only don't want to create a new shape -----
  369.     if (fDrawPart->IsReadOnly(ev))
  370.     {
  371.         FW_Beep();
  372.         return FW_kHandled;
  373.     }
  374.     
  375.     // ----- Create a new shape -----
  376.     CBaseShape *theShape =  fDrawPartContent->NewShape(ev, fDrawPart->GetTool() - kLine + kLineShape);
  377.     
  378.     FW_TRY
  379.     {
  380.         FW_CStyle trackStyle(fDrawPart->GetRenderVerb() == kFillOnly ? FW_kFixedPos1 : fDrawPart->GetPenSize(), FW_kGrayPat);
  381.         FW_CInk trackInk(FW_kRGBBlack, FW_kRGBWhite, FW_kXOr);
  382.         theShape->ChangeRenderVerb(ev, kFrameOnly);
  383.         theShape->SetFrameInk(trackInk);
  384.         theShape->SetFrameStyle(trackStyle);
  385.         
  386.         CShapeTracker tracker(ev, this, theFacet, theShape, fDrawPart->IsAutoGridOn());
  387.         if (tracker.Track(ev, theMouseEvent))
  388.         {
  389.             
  390.             CDrawShapeCommand* cmd = FW_NEW(CDrawShapeCommand,
  391.                                             (ev, fDrawPart, fDrawFrame, selection, theShape));
  392.             if (cmd->Execute(ev))
  393.             {
  394.                 theShape->SetFrameInk(FW_kNormalInk);
  395.                 theShape->SetFrameStyle(FW_kNormalStyle);
  396.                 
  397.                 FW_CColor color;
  398.         
  399.                 theShape->ChangeRenderVerb(ev, fDrawPart->GetRenderVerb());
  400.                 theShape->ChangePenSize(ev, fDrawPart->GetPenSize());
  401.                         
  402.                 fDrawPart->GetFrameColor(color);
  403.                 theShape->ChangeFrameColor(ev, color);
  404.         
  405.                 fDrawPart->GetFillColor(color);
  406.                 theShape->ChangeFillColor(ev, color);
  407.         
  408.                 theShape->ChangeFramePattern(ev, fDrawPart->GetFramePattern());
  409.                 theShape->ChangeFillPattern(ev, fDrawPart->GetFillPattern());
  410.                 
  411.                 FW_CRect dragRect;
  412.                 theShape->GetDragRect(dragRect);
  413.     
  414.                 FW_CAcquiredODShape aqShape = ::FW_NewODShape(ev, dragRect);
  415.                 
  416.                 CDrawFacetClipper facetClipper(fDrawPart);
  417.                 facetClipper.Clip(ev, fDrawFrame->GetPresentation(ev), aqShape);
  418.                 
  419.                 FW_CViewContext vc(ev, this, theMouseEvent.GetFacet(ev));
  420.                 theShape->RenderShape(ev, theFacet, vc);
  421.                 
  422.                 theShape->GetUpdateBox(ev, aqShape);
  423.                 Invalidate(ev, aqShape, TRUE);        // want to invalidate all frames
  424.                 
  425.                 // ----- Because drawing has already been done in this facet -----
  426.                 ViewContentToFrame(ev, aqShape);
  427.                 theFacet->Validate(ev, aqShape, NULL);
  428.             }
  429.         }
  430.     }
  431.     FW_CATCH_BEGIN
  432.     FW_CATCH_EVERYTHING()
  433.     {
  434.         theShape->Release();
  435.         FW_THROW_SAME();
  436.     }
  437.     FW_CATCH_END
  438.     
  439.     theShape->Release();
  440.     return FW_kHandled;
  441. }
  442.  
  443. //----------------------------------------------------------------------------------------
  444. // CDrawView::DrawGrid
  445. //----------------------------------------------------------------------------------------
  446.  
  447. void CDrawView::DrawGrid(Environment *ev, FW_CGraphicContext& gc, const FW_CRect& invalidRect)
  448. {
  449. FW_UNUSED(ev);
  450.     if (fDrawFrame->IsGraphicsGridOn())
  451.     {
  452.         FW_BitPattern vertical = {0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  453.         FW_BitPattern horizontal = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80};
  454.         FW_CPattern verticalPat(vertical);
  455.         FW_CPattern horizontalPat(horizontal);
  456.         
  457.         FW_Fixed minY = FW_IntToFixed(72 * (FW_FixedToInt(invalidRect.top) / 72));
  458.         FW_Fixed maxY = FW_IntToFixed(72 * (FW_FixedToInt(invalidRect.bottom + FW_kFixed72) / 72));
  459.         FW_Fixed minX = FW_IntToFixed(72 * (FW_FixedToInt(invalidRect.left) / 72));
  460.         FW_Fixed maxX = FW_IntToFixed(72 * (FW_FixedToInt(invalidRect.right + FW_kFixed72) / 72));
  461.  
  462.         // skip top-most and left-most lines
  463.         FW_Fixed startX = (minX == FW_kFixed0) ? FW_kFixed72 : minX;
  464.         FW_Fixed startY = (minY == FW_kFixed0) ? FW_kFixed72 : minY;
  465.         
  466.         FW_CStyle lineStyle(FW_kFixed0, verticalPat);
  467.         FW_CLineShape line(startX, minY, startX, maxY, FW_kNormalInk, lineStyle);
  468.  
  469.         FW_Fixed x,y;
  470.         for (x = startX; x <= maxX; x += FW_kFixed72)
  471.         {
  472.             line.Render(gc);
  473.             line.MoveShape(FW_kFixed72, FW_kFixed0);
  474.         }
  475.         
  476.         line.GetStyle().SetPattern(horizontalPat);
  477.         line.SetLineStart(minX, startY);
  478.         line.SetLineEnd(maxX, startY);
  479.         
  480.         for (y = startY; y <= maxY; y += FW_kFixed72)
  481.         {
  482.             line.Render(gc);
  483.             line.MoveShape(FW_kFixed0, FW_kFixed72);
  484.         }
  485.  
  486.         FW_CPoint pageSize = fDrawPart->GetPageSize();
  487.         FW_BitPattern edgePat = {0x66, 0xCC, 0x99, 0x33, 0x66, 0xCC, 0x99, 0x33};
  488.         FW_CStyle edgeStyle(FW_IntToFixed(4), edgePat);
  489.         for (x = FW_IntToFixed(-2); x <= maxX; x += pageSize.x)
  490.         {
  491.             FW_CPoint startPt(x, minY);
  492.             FW_CPoint endPt(x, maxY);
  493.             FW_CLineShape::RenderLine(gc, startPt, endPt, FW_kNormalInk, edgeStyle);
  494.         }
  495.         for (y = FW_IntToFixed(-2); y <= maxY; y += pageSize.y)
  496.         {
  497.             FW_CPoint startPt(minX, y);
  498.             FW_CPoint endPt(maxX, y);
  499.             FW_CLineShape::RenderLine(gc, startPt, endPt, FW_kNormalInk, edgeStyle);
  500.         }
  501.     }
  502. }
  503.  
  504. //----------------------------------------------------------------------------------------
  505. // CDrawView::SizeChanged
  506. //----------------------------------------------------------------------------------------
  507. //    My content view size has changed I need to clip my embedded facets. It's better to do it
  508. //    here than in CDrawFrame::FrameShapeChanged because my frame shape can be changing but
  509. //    my bounds may not.
  510.  
  511. void CDrawView::SizeChanged(Environment* ev, const FW_CPoint& oldSize)
  512. {
  513.     FW_CSuperView::SizeChanged(ev, oldSize);
  514.     
  515.     // ----- Set purgeable flag according to visibility -----
  516.     FW_CRect bounds = GetBoundsInContent(ev);
  517.     CDrawContentShapeIterator ite(fDrawPartContent);
  518.     for (CBaseShape* theShape = ite.First(); ite.IsNotComplete(); theShape = ite.Next())
  519.         theShape->MakePurgeable(ev, fDrawFrame, bounds);
  520.  
  521.     // ----- Reclip -----
  522.     CDrawFacetClipper facetClipper(fDrawPart);
  523.     facetClipper.Clip(ev, fDrawFrame->GetPresentation(ev));
  524. }
  525.  
  526. //----------------------------------------------------------------------------------------
  527. //    CDrawView::Create
  528. //----------------------------------------------------------------------------------------
  529.  
  530. void* CDrawView::Create(FW_CReadableStream& stream, FW_ClassTypeConstant type)
  531. {
  532. FW_UNUSED(stream);
  533. FW_UNUSED(type);
  534.     FW_SOMEnvironment ev;
  535.     return new CDrawView(ev);
  536. }
  537.  
  538. //----------------------------------------------------------------------------------------
  539. //    CDrawView::Destroy
  540. //----------------------------------------------------------------------------------------
  541.  
  542. void CDrawView::Destroy(void* object, FW_ClassTypeConstant type)
  543. {
  544. FW_UNUSED(type);
  545.     CDrawView* self = (CDrawView*) object;
  546.     delete self;
  547. }
  548.  
  549. //----------------------------------------------------------------------------------------
  550. //    CDrawView::Flatten
  551. //----------------------------------------------------------------------------------------
  552.  
  553. void CDrawView::Flatten(Environment* ev, FW_CWritableStream& archive) const
  554. {
  555.     FW_CSuperView::Flatten(ev, archive);
  556. }
  557.  
  558. //----------------------------------------------------------------------------------------
  559. //    CDrawView::InitializeFromStream
  560. //----------------------------------------------------------------------------------------
  561.  
  562. void CDrawView::InitializeFromStream(Environment* ev, FW_CReadableStream& stream)
  563. {
  564.     FW_CSuperView::InitializeFromStream(ev, stream);
  565.     
  566.     FW_OObjectRegistry*    registry = stream.GetRegistry();
  567.     FW_CFrame* frame = (FW_CFrame*) registry->LookupByID(ev, FW_kPreregisteredFrameObject);
  568.     FW_ASSERT(frame != NULL);
  569.     
  570.     fDrawFrame = FW_DYNAMIC_CAST(CDrawFrame, frame);
  571.     FW_ASSERT(fDrawFrame != NULL);
  572.     
  573.     FW_CEmbeddingPart* part = fDrawFrame->GetPart(ev);
  574.     fDrawPart = FW_DYNAMIC_CAST(CDrawPart, part);
  575.     FW_ASSERT(fDrawPart != NULL);
  576.  
  577.     fDrawPartContent = fDrawPart->GetDrawContent();
  578.     FW_ASSERT(fDrawPartContent != NULL);
  579. }
  580.  
  581.